package com.code.gen.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Map;

import com.code.gen.bean.bo.CodeGenProperties;
import com.code.gen.bean.bo.template.CodeGenTemplate;
import com.code.gen.enums.ECodeGenTemplateType;
import com.sojson.util.file.FileUtil;

import lombok.Data;

/**
 * 文件工具类
 * 
 * @author liu
 * @Date 2020-06-15 14:45:33
 * @Description
 *
 */
@Data
public class CodeGenFileUtil {

    private CodeGenProperties properties;

    public CodeGenFileUtil(CodeGenProperties properties) {
        this.properties = properties;
    }

    /**
     * 创建文件
     * 
     * @throws Exception
     */
    public void createFile() throws Exception {
        Map<String, CodeGenTemplate> contents = properties.getContents();
        for (CodeGenTemplate template : contents.values()) {
            if (template.getType() == ECodeGenTemplateType.MAIN) {
                createFile(template);
            }
        }
    }

    /**
     * 获取压缩文件字节流
     * 
     * @param map
     * @return
     * @throws Exception
     */
    public void getZip(Map<String, byte[]> map) throws Exception {
        Map<String, CodeGenTemplate> contents = properties.getContents();
        for (CodeGenTemplate template : contents.values()) {
            if (template.getType() == ECodeGenTemplateType.MAIN) {
                String path = getZipPath(template);
                map.put(path, template.getContent().getBytes());
            }
        }
    }

    /**
     * 创建文件
     * 
     * @param template
     * @throws Exception
     */
    private void createFile(CodeGenTemplate template) throws Exception {
        String path = template.getPath();
        String pathAll = path + "/" + template.getFileName() + template.getFileNameSuffix();
        File file = null;
        if (template.getPathIsAbsolute()) {
            file = new File(pathAll);
        } else if (template.getPathIsClasspath()) {
            String javaPath = "src/main/resources/";
            path = javaPath + path;
            file = new File(javaPath + pathAll);
        } else {
            String javaPath = "src/main/java/";
            path = javaPath + path;
            file = new File(javaPath + pathAll);
        }
        // 删除文件
        deleteFileByFile(file);
        // 创建目录
        makeDirectoryByPathname(path);
        // 创建文件
        createNewFileByFile(file);

        FileWriter writer = null;
        BufferedWriter buffered = null;
        try {
            writer = new FileWriter(file);
            buffered = new BufferedWriter(writer);
            buffered.write(template.getContent());
            buffered.flush();
        } finally {
            FileUtil.closeStream(buffered, writer);
        }
    }

    /**
     * 获取压缩文件路径
     * 
     * @param template
     * @return
     * @throws Exception
     */
    private String getZipPath(CodeGenTemplate template) throws Exception {
        String x = "/";
        String m = ":";
        String mx = m + x;
        String path = template.getPath();
        String pathAll = path + x + template.getFileName() + template.getFileNameSuffix();
        if (template.getPathIsAbsolute()) {
            if (pathAll.startsWith(x)) {
                pathAll = pathAll.substring(1);
            } else if (pathAll.contains(mx)) {
                pathAll = pathAll.substring(3);
            } else if (pathAll.contains(m)) {
                pathAll = pathAll.substring(2);
            }
        } else if (template.getPathIsClasspath()) {
            String javaPath = "src/main/resources/";
            path = javaPath + path;
            pathAll = javaPath + pathAll;
        } else {
            String javaPath = "src/main/java/";
            path = javaPath + path;
            pathAll = javaPath + pathAll;
        }

        return pathAll;
    }

    /**
     * 判断文件是否存在，存在则删除</BR>
     * 因为File无法删除非空目录,所以需要先递归所有子文件</BR>
     * 
     * @param file
     */
    private static void deleteFileByFile(File file) {
        // 判断文件是否存在
        if (file.exists()) {
            // 判断是文件还是目录
            if (file.isFile()) {
                // 是文件就删除
                file.delete();
            } else {
                // 是目录就递归调用此方法
                // 获取目录下的所有文件
                File[] listFiles = file.listFiles();
                for (File f : listFiles) {
                    deleteFileByFile(f);
                }
            }
        }
    }

    /**
     * 判断目录是否存在，不存在则创建
     * 
     * @param pathName 文件路径
     */
    private static void makeDirectoryByPathname(String pathName) {
        File file = new File(pathName);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 判断文件是否存在，不存在则创建
     * 
     * @param file
     * @throws Exception
     */
    private static void createNewFileByFile(File file) throws Exception {
        if (!file.exists()) {
            file.createNewFile();
        }
    }

}